﻿using System.Collections.Specialized;
using System.Data;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using Microsoft.VisualStudio.DebuggerVisualizers;
using WebVisualizers.Types;

namespace WebVisualizers.ObjectSource
{
    /// <summary>
    /// Specialized ObjectSource for System.Web.UI.Page
    /// </summary>
    /// <remarks>
    /// This class is needed because the System.Web.UI.Page is not serializable and IVisualizerObjectProvider expects it to be serializable
    /// In the GetData Method System.Web.UI.Page will be turned into something that is Serializable
    /// </remarks>
    public class WebPageObjectSource : VisualizerObjectSource 
    {
        /// <summary>
        /// Takes a Page object get Data from it and store it into PageData
        /// Replace the target object wit PageData and call the base functionality
        /// </summary>
        /// <param name="target">System.Web.UI.Page</param>
        /// <param name="outgoingData">Output stream (PageData)</param>
        public override void GetData(object target, System.IO.Stream outgoingData)
        {
            if (target != null)
            {
                Page page = (Page)target;
                PageData pageData = new PageData();
                pageData.DataTableList.Add(GetNameValueCollection("Servervariables", page.Request.ServerVariables));
                pageData.DataTableList.Add(GetNameValueCollection("Forms", page.Request.Form));
                pageData.DataTableList.Add(GetNameValueCollection("Querystring", page.Request.QueryString));
                pageData.DataTableList.Add(GetApplicationState("Application State", page.Application));
                pageData.DataTableList.Add(GetSessionState("Session State", page.Session));

                target = pageData;
            }
            base.GetData(target, outgoingData);
        }

        /// <summary>
        /// Converts a NameValueCollection into a DataTable
        /// </summary>
        private DataTable GetNameValueCollection(string dataTableName, NameValueCollection nvc)
        {
            DataTable dt = CreateNameValueDataTable(dataTableName);
            foreach (string item in nvc)
            {
                DataRow dr = dt.NewRow();
                dt.Rows.Add(dr);
                dr[0] = item;
                dr[1] = nvc[item];
            }
            return dt;
        }

        /// <summary>
        /// Converts the HTTPSessionState object into a DataTable
        /// </summary>
        private DataTable GetSessionState(string dataTableName, HttpSessionState session)
        {
            DataTable dt = CreateNameValueDataTable(dataTableName);
            foreach (string item in session)
            {
                DataRow dr = dt.NewRow();
                dt.Rows.Add(dr);
                dr[0] = item;
                dr[1] = session[item];
            }
            return dt;
        }

        /// <summary>
        /// Converts the HttpApplicationState object into a DataTable
        /// </summary>
        private DataTable GetApplicationState(string dataTableName , HttpApplicationState application)
        {
            DataTable dt = CreateNameValueDataTable(dataTableName);
            foreach (string item in application)
            {
                DataRow dr = dt.NewRow();
                dt.Rows.Add(dr);
                dr[0] = item;
                dr[1] = application[item];
            }
            return dt;
        }

        /// <summary>
        /// Creates a DataTable with two columns (Name/Value)
        /// </summary>
        private DataTable CreateNameValueDataTable(string dataTableName)
        {
            DataTable dt = new DataTable(dataTableName);
            dt.Columns.Add("Name");
            dt.Columns.Add("Value");

            return dt;
        }
    }
}
